﻿using PIMS.Interface;
using PIMS.Utils;
using PIMS.XmlModel;
using PIMS.XmlModel.Snap7;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;

namespace PIMS
{
    public partial class FormPLCStatePanel : DockContent
    {
        int position = 0;

        List<ICommunication> listPlc = new List<ICommunication>();
        Dictionary<string, Label> myDict = new Dictionary<string, Label>();
        private IOMonitor myIOMonitor = null;

        public FormPLCStatePanel()
        {
            InitializeComponent();

        }

        private void FormPLCPanel_Load(object sender, EventArgs e)
        {

        }


        private void FormPLCStatePanel_Shown(object sender, EventArgs e)
        {
            //Init();
            //this.timer1.Enabled = true;
            try
            {
                Common.InitPLC();
            }
            catch (Exception ex)
            {
                Common.log.Error("", ex);
                Common.d.DebugMsg(ex.Message);
            }
            Init();
            this.timer1.Enabled = true;

            //RestFulService.HostRestFulService.StartService();
        }

        /// <summary>
        /// 动态生成UI控件
        /// </summary>
        private void Init()
        {
            try
            {
                while (!Common.initPlcOK)
                {
                    Thread.Sleep(100);
                }

                //AddControl(Common.allPLC.weightPLC);
                //AddControl(Common.allPLC.packerPLC);
                AddControl(Common.allPLC.palPLC);
                AddControl(Common.allPLC.labelPLC);
                //AddControl(Common.allPLC.otherPLC);

                this.position += 30;

                if (Common.pimsConfig.GetAppValueByKey("svrIP") != "127.0.0.1")
                {
                    AddControl("SAP", Common.pimsConfig.GetAppValueByKey("svrIP"));
                }

                if (Common.pimsConfig.GetAppValueByKey("wmsIP") != "127.0.0.1")
                {
                    AddControl("WMS", Common.pimsConfig.GetAppValueByKey("wmsIP"));
                }

                if (Common.pimsConfig.GetAppValueByKey("erpIP") != "127.0.0.1")
                {
                    AddControl("ERP", Common.pimsConfig.GetAppValueByKey("erpIP"));
                }

            }
            catch (Exception ex)
            {
                Common.log.Error("", ex);
                Common.d.DebugMsg(ex.Message, InfoLevel.error);
            }
        }

        private void AddControl(ICommunication[] plc)
        {
            if (plc != null)
            {
                this.panel0.Visible = false;
                for (int i = 0; i < plc.Length; i++)
                {
                    this.position += 30;
                    Label labelname = new Label();
                    labelname.AutoSize = true;
                    labelname.Size = new Size(100, 20);
                    labelname.Location = new Point(30, 10 + this.position); //9 + this.position
                    labelname.Font = new Font("宋体", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
                    labelname.Text = plc[i].GetDeviceName();
                    if (!labelname.Text.EndsWith(":")) labelname.Text += ":";
                    labelname.TextAlign = ContentAlignment.MiddleCenter;
                    labelname.Visible = true;
                    labelname.Tag = plc[i].GetIPAddr();
                    labelname.DoubleClick += Labelname_DoubleClick;

                    Label labelPlc = new Label();
                    labelPlc.AutoSize = true;
                    labelPlc.Size = new Size(50, 20);
                    labelPlc.Location = new Point(110, 10 + this.position); //9 + this.position
                    labelPlc.Font = new Font("宋体", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
                    labelPlc.Text = "脱机";
                    labelPlc.Visible = true;
                    labelPlc.Tag = plc[i];
                    labelPlc.DoubleClick += LabelPlc_DoubleClick;

                    this.Controls.Add(labelname);
                    this.Controls.Add(labelPlc);

                    this.toolTip1.SetToolTip(labelname, string.Format("双击自动PING {0}",plc[i].GetIPAddr()));
                    this.toolTip1.SetToolTip(labelPlc, "双击可查看通迅的变量");

                    listPlc.Add(plc[i]);
                    myDict.Add(plc[i].GetDeviceName(), labelPlc);
                }

            }

        }

        private void AddControl(string name, string ipAddr)
        {
            this.position += 30;
            Label labelname = new Label();
            labelname.AutoSize = true;
            labelname.Size = new Size(100, 20);
            labelname.Location = new Point(30, 10 + this.position); //9 + this.position
            labelname.Font = new Font("宋体", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
            labelname.Text = name;
            if (!labelname.Text.EndsWith(":")) labelname.Text += ":";
            labelname.TextAlign = ContentAlignment.MiddleCenter;
            labelname.Visible = true;
            labelname.Tag = ipAddr;
            labelname.DoubleClick += Labelname_DoubleClick;            

            Label labelPlc = new Label();
            labelPlc.AutoSize = true;
            labelPlc.Size = new Size(50, 20);
            labelPlc.Location = new Point(110, 10 + this.position); //9 + this.position
            labelPlc.Font = new Font("宋体", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
            labelPlc.Text = "脱机";
            labelPlc.Visible = true;

            this.toolTip1.SetToolTip(labelname, ipAddr);

            this.Controls.Add(labelname);
            this.Controls.Add(labelPlc);

            IPPara para = new IPPara();
            para.ip = ipAddr;
            para.label = labelPlc;
            new Thread(new ParameterizedThreadStart(Thread_CheckIpOnLine)) { IsBackground = true }.Start(para);
        }

        private void Labelname_DoubleClick(object sender, EventArgs e)
        {
            Label label = (Label)sender;
            string ipAddr = label.Tag.ToString();

            DialogResult a = MessageBox.Show(string.Format("是否自动PING {0} ?", ipAddr), label.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (a == DialogResult.Yes)
            {
                Process p = new Process();
                p.StartInfo.FileName = "cmd.exe"; //设定程序名
                p.StartInfo.Arguments = String.Format("/k ping {0} -t", ipAddr);
                p.StartInfo.UseShellExecute = false; //关闭Shell的使用
                p.StartInfo.RedirectStandardInput = false; //重定向标准输入
                p.StartInfo.RedirectStandardOutput = false; //重定向标准输出
                p.StartInfo.RedirectStandardError = false; //重定向错误输出
                p.StartInfo.CreateNoWindow = false; //设置不显示窗口
                p.Start();
                p.Close();
            }
        }

        private void LabelPlc_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                Label label = (Label)sender;
                ICommunication ic = (ICommunication)label.Tag;
                IPLCXModel ipx = (IPLCXModel)ic.xModel;

                if(this.myIOMonitor != null)
                {
                    MessageBox.Show("只能打开一个IO监视窗口！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                DialogResult a = MessageBox.Show(string.Format("是否打开‘{0}’的IO监视窗口?", ic.GetDeviceName()), label.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (a == DialogResult.Yes)
                {
                    // Snap7XModel s7 = ipx as Snap7XModel;
                    // this.myIOMonitor = new IOMonitor(ic, s7);
                    this.myIOMonitor = new IOMonitor(ic, ipx);
                    this.myIOMonitor.Text = ic.GetDeviceName() + " PLC数据监控";
                    this.myIOMonitor.FormClosing += new FormClosingEventHandler(myForm_FormClosing);
                    this.myIOMonitor.Show();
                }
            }
            catch (Exception ex)
            {
                Common.log.Error("", ex);
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        void myForm_FormClosing(object sender,FormClosingEventArgs e)
        {
            this.myIOMonitor = null;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                foreach(ICommunication plc in listPlc)
                {
                    if(plc!=null)
                    {
                        Label label = myDict[plc.GetDeviceName()];
                        if (plc.IsConnected)
                        {
                            label.Text = "在线";
                            label.ForeColor = Color.Black;
                        }
                        else
                        {
                            label.Text = "离线";
                            label.ForeColor = Color.Red;
                        }
                    }
                }
            }
            catch(Exception ex)
            {
                Common.log.Error("", ex);
                Common.d.DebugMsg(ex.Message,InfoLevel.error);
            }
        }

        void Thread_CheckIpOnLine(object obj)
        {
            try
            {
                IPPara para = (IPPara)obj;
                string ip= para.ip;
                Label label=para.label;
                while (true)
                {
                    bool onLine = false;
                    try
                    {
                        onLine = IPTools.IsIPOnLine(ip);
                    }
                    catch
                    {
                        onLine = false;
                        label.ForeColor = Color.Black;
                    }
                    this.Invoke(
                    new Action(() => {
                        if (onLine)
                        {
                            label.Text = "在线";
                            label.ForeColor = Color.Black;
                        }
                        else
                        {
                            label.Text = "离线";
                            label.ForeColor = Color.Red;
                        }
                    }));

                    Thread.Sleep(3000);
                }
            }
            catch
            { }
        }

        
    }

    struct IPPara
    {
        public string ip;
        public Label label;
    }
}
